<?php
/**
 * Base Controller class.
 * 
 * @package adroit
 * @subpackage controller
 */
class BaseController {
    
    /**
     * The view associated with this controller
     *
     * @var BaseView
     */
    public $view;
    
    public $layout;
    
    public static $FILTER_ACTION = 'filterAction';

    public static $LOGGED_IN = 'loggedIn';

	public $crud = null;

    /**
     * @var boolean Flag for restricted access
     */
    public $restricted = false;

    /**
     * @var Array Data passed on to View
     */
    public $data = Array();
    
    /**
     * Constructor
     *
     * @return BaseController
     */
    public function BaseController() {

    }

    /**
     * Main entry point into controller.  Executes the associated model and view.
     *
     * @param Array $requestData
     */
    public function process($requestData, $action) {
        $this->data['alertHandler'] = Adroit::$alerts;
        $this->data['ALERT_TYPE_ERROR'] = AdroitAlertHandler::$TYPE_ERROR;
        $this->data['ALERT_TYPE_SUCCESS'] = AdroitAlertHandler::$TYPE_SUCCESS;
        $this->data['FILTER_ACTION'] = self::$FILTER_ACTION;
        $this->applyFilters($requestData, $action);
        $actionMethod = strtolower($action) . 'Action';
		if($this->crud !== null) {
			$actionMethod = ($actionMethod == 'Action' ? 'indexAction' : $actionMethod);
			$handler = new CrudHandler($this->crud, $this->data);
			$handler->$actionMethod($requestData);
			$this->data = array_merge($this->data, $handler->data);
			$this->data['plural'] = $handler->plural;
			$this->data['single'] = $handler->single;
		}else {
        	if(method_exists($this, $actionMethod)) {
	        	$this->$actionMethod($requestData);
	        }
		}
    }

    /**
     * Adds errors to the AdroitAlertHandler object
     *
     * @param Array $errors Error messages
     */
    protected function addValidationErrors($errors) {
        foreach($errors AS $error) {
            Adroit::$alerts->addAlert($error, AdroitAlertHandler::$TYPE_ERROR);
        }
    }
    
    public static function redirect($controller='', $action='') {
        if(count(Adroit::$alerts->alerts) > 0) {
            $_SESSION[AdroitAlertHandler::$SESSION_KEY] = Adroit::$alerts;
        }
    	header('location: ' . WEB_ROOT . $controller . ($action != '' ? '/' : '') . $action);
    }
    
    public static function forward($controller='', $action='') {
    	Adroit::$controller = $controller;
    	Adroit::$action = $action;
    }
    
    private function applyFilters($requestData, $action) {
        if(@$this->filters != null) {
            foreach($this->filters AS $filter) {
            	$apply = @$filter['applyTo'];
            	$exclude = @$filter['exclude'];
                if($apply == '' && $exclude == '') {
                    $apply = 'all';
                }
                $filterValue = $filter['filter'];
                if($apply === 'all') {
            	    $this->applyFilter($filterValue, $requestData);
                }else if(@is_array($apply) && in_array(strtolower($action), $apply)) {
            		$this->applyFilter($filterValue, $requestData);
                }else if($apply === strtolower($action)) {
                	$this->applyFilter($filterValue, $requestData);
                }else if(is_array($exclude) && !in_array(strtolower($action), $exclude)) {
                	$this->applyFilter($filterValue, $requestData);
                }else if($exclude !== '' && !is_array($exclude) && $exclude !== strtolower($action)) {
					$this->applyFilter($filterValue, $requestData);
				}
            }
        }
    }
    
    private function applyFilter($filter, $requestData) {
    	if(file_exists(APP_PATH . 'filter/' . substr($filter, 0, strlen($filter)-6) . '.filter.php')) {
            $filterClass = new $filter;
            $filterClass->process($this, $requestData);
        }else {
            $this->$filter($requestData);
        }
    }

	protected function setClassProperties($model) {
		$class = new ReflectionClass($model);
		$properties = $class->getProperties();
		$attributes = array();
		foreach($properties AS $property) {
			if($property->isPublic() === true) {
				$attributes[] = $property->getName();
			}
		}
		$this->data[strtolower($model) . 'Properties'] = $attributes;
	}
}

?>